home *** CD-ROM | disk | FTP | other *** search
- ; DDE.LSP
- ;
- ; ________________________________________________________________________
- ;
- ; (C) Copyright 1990-1993 by Autodesk, Inc.
- ; by Phil Ford
- ;
- ; Permission to use, copy, modify, and distribute this software and its
- ; documentation for any purpose and without fee is hereby granted.
- ;
- ; THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
- ; ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
- ; MERCHANTABILITY ARE HEREBY DISCLAIMED.
- ; ________________________________________________________________________
- ;
- ;
- ; DDE.LSP data between AutoCAD and a concurrently running spreadsheet
- ; program using the Dynamic Data Exchange feature of Windows.
- ; This program relies on the ADS program, DDELISP.EXE, to call Windows.
- ;
- ;
- ;---------------------------
- ;
-
- ; Main AutoLISP commands:
- ; c:send - send tables and drawing to DDE app
- ; c:get - read data back in and modify any changed entities
- ; sendset - send a selection set
- ;
- ; Main DDE functions (implemented with ADS functions in DdeLisp.exe):
- ; ddeprompt - Open channel to default app, put up dialog if failure.
- ; The DDE dialog saves values in windows\ddelisp.ini.
- ; setddeformat - AutoCAD Entity filters and layout
- ; 0 = all data, use entity names
- ; 1 = all data, use handles and not names
- ; 2 = decimal handle, handle, tag1, attr1; dec handle,
- ; handle, tag2, attr2; ...
- ; each block insert on one row
- ; 3 = same as 2 but without tags
- ; senddrawing - sends tables, 5 blank lines, rest of drawing
- ; moddrawing - imports data from DDE program and modifies
- ; any drawing entities that have changed
- ; pokealltbl - sends drawing table data to remote app
- ; pokeall - sends drawing entities
- ; pokeset - sends selection set
- ; advise - set up warm link on last item sent
- ; reqmod - requests data and modifies drawing entities
- ; with the data, using a specified range (speed opt)
- ; ddefree - call after the DDE request data function
- ; "request", to free the shared data transferred from
- ; a remote application.
- ; ddedone - terminate all DDE channels and free memory
-
- ; Main global variables:
- ; chnl - DDE channel number (32 allowed)
- ; topic - work file (spreadsheet name)
- ; item - DDE item (cell range description)
- ; row1, col1 - start of spreadsheet data
- ; rowcnt - sum of rows used by last drawing
- ; transmission
-
-
-
- ; Send all the tables and entities to the remote
- ; DDE program (app) on the channel created by ddestart
- ; using "senddrawing" function
- (defun c:send ()
- (chkdde) ;Check open chnl, prompt user if not
- (unadvise chnl "") ;Clear hot link on last item sent
- (sendheading)
- (princ "\nSending drawing data...\n")
- (setq rowcnt (senddrawing row1))
- (advise chnl "" linkcommand) ;Set up warm link on last
- ; item sent (""). When new data comes
- ; in, interrupt AutoCAD and request
- ; the moddrawing function
- (princ "\nNumber of rows used by drawing: ")
- (princ rowcnt)
- (princ "\n")
- (princ)
- )
-
-
-
- ; Request data and modify drawing
- (defun c:get ()
- (chkdde) ;Check open chnl, prompt user if not
- (setq en (entnext)) ;get first entity name
- (princ "Receiving data and modifying drawing...\n")
- (if (= rowcnt 0)(setq rowcnt 18000)) ;to read in spreadsheet data when
- ; we wrote it in a previous
- ; session, we don't
- ; know the number of rows. Just
- ; set high limit on read, so
- ; "moddrawing" will continue until
- ; end of spreadsheet data.
- (setq modcnt (moddrawing row1 rowcnt))
- )
-
-
- ; Send all the tables and then the entities to the remote
- ; DDE program (app) on the channel created by ddestart,
- ; using "pokealltbl" and "pokeall"
- (defun sendall ()
- (chkdde) ;Check open chnl, prompt user if not
- ;Send all the tables
- (setq tabrows (lenalltbl)) ;in case you need the length before
- ; you send them
- (setq row row1)
- (setq tblrows (pokealltbl chnl row col1)) ;send all the tables
- (setq row (+ row tblrows)) ;set row to end of drawing data in
- ; the spreadsheet
- (setq row (+ row 5)) ;leave blank lines
- (princ "Rows used by the tables: ")
- (princ tblrows)
- (princ "\n")
-
- ;TABLE Definitions
- ;VPORT 0
- ;LTYPE 1
- ;LAYER 2
- ;STYLE 3
- ;VIEW 4
- ;UCS 5
- ;BLOCK 6
- ;DIMSTYLE 7
-
- (setq blkrows (lentbl 6)) ;6=BLOCK
- (princ "\nNumber of rows in blocks: ")
- (princ blkrows)
- (princ "\n")
-
- ;Send a table individually--this is just a
- ; test. We already sent all the tables,
- ; including the BLOCK table.
- ; (setq item (cellstr row col1 rowcnt 4)) ;from row, col, rows sent
- ; ; previously (4 cols)
- ; (setq rowcnt (poketbl chnl item 6)) ;send BLOCK table (6)
- ; ; to spreadsheet with DDE
- ; (setq row (+ row rowcnt))
- ; (setq row (+ row 1))
- ; (princ "Rows used by the blocks: ")
- ; (princ rowcnt)
- ; (princ "\n")
-
-
- (princ "\nSending drawing data...\n")
- (setq en (entnext)) ;get first entity name
- (setq rowcnt (pokeall chnl en row col1)) ;send whole drawing to remote
- ; spreadsheet with DDE
- (princ "\nNumber of rows used by entities: ")
- (princ rowcnt)
- (princ "\n")
-
- (princ)
- )
-
-
- ; Send a selection set to a remote application, using
- ; "pokeset"
- (defun sendset ()
- (chkdde) ;Check open chnl, prompt user if not
- (sendheading)
- (setq frmt (getddeformat))
- (if (< frmt 2)
- (setq sset (ssget)) ;get a selection set of all codes
- (setq sset (ssget "X" (list (cons 0 "ATTRIB"))))
- ;just attributes
- )
- (unadvise chnl "") ;Clear hot link on last item sent
- (setq rowcnt (pokeset chnl sset row1 col1)) ;send set to remote
- ; spreadsheet with DDE
- (advise chnl "" linkcommand) ;Set up warm link on last
- ; item sent (""). When new data comes
- ; in, interrupt AutoCAD and request
- ; the moddrawing function
- (setq sset nil)
- (princ "Rows: ")
- (princ rowcnt)
- (princ)
- )
-
-
-
-
- ; Read DDE data (from DDE remote app)
- ; starting at a certain row, and modify any entities
- ; that have changed. Allows
- ; column 1 values of less than -4 for comments in
- ; spreadsheet. -1 is normal entity group code in column 1.
- ; Demonstrates "reqmod" function.
- (defun mod ()
- (chkdde) ;Check open chnl, prompt user if not
- (setq mrow1 (getint "\nStart row: "))
- (setq nrows (getint "\nNumber of rows: "))
- (setq item (cellstr mrow1 col1 nrows 4)) ;from row, col, rows sent
- ; previously (4 cols)
- (setq mrowcnt (reqmod chnl item)) ;request range of data, modify
- ; entities that have changed
- (setq entcnt (modcount))
- (ddefree chnl) ;free shared data from remote app
- (princ "\nEntities modified: ")
- (princ entcnt)
- (princ "\n")
- (princ "Rows: ")
- (princ mrowcnt)
- (princ)
- )
-
-
- ;
- ;
- ; Slower versions, transfer entities one at a time
- ;
- ;
-
- ; Send all the entities in the drawing to the remote app
- ; one at a time. Demonstates DDE functions
- ; "poke", "request", "execute", and entity transfer function
- ; "entpokecell"
- (defun sendall2 () ;Dynamic Data Exchange Sample
- ; Usage
- (chkdde) ;Check open chnl, prompt user if not
- (setq cell (cellstr 1 1 1 1)) ;cell item "R1C1", row 1 col 1,
- ; 1 number of rows, 1 ncols
-
- ;Test DDE functions; poke, request, and execute
- (poke chnl cell
- "AutoCAD / Excel Demo .25...............40.................60.................80")
- ;poke-send data for the cell, check
- ; string length abilities of system
- (setq data (request chnl cell)) ;request-get data from a cell
- (ddefree chnl) ;free request data (shared data from
- ; remote app)
- (princ "Data from Spreadsheet: \n")
- (princ data)
- (princ "\n")
- (setq cell (cellstr 1 3 1 1)) ;cell item "R1C1", row 1 col 3
- (setq execstr "[SELECT(\"R1C1\")][FORMULA(\"AutoCAD Graphics Data\")]")
- (execute chnl execstr)
-
-
- ;Send entities one by one
- (setq en (entnext)) ;get first entity name
- (setq row row1 col col1) ;start spread sheet in row 2, col 1
- (setq rowcnt 0)
- (while (not (null en))
- (setq rows (entpokecell chnl en row col))
- (setq rowcnt (+ rowcnt rows))
- ;fill cells with entity data list.
- ; rows is the number of items
- ; in list
- (setq row (+ row rows)) ;move down to bottom of that entity
- ; in spreadsheet
- (setq en (entnext en)) ;get next entity name
- (princ "\nNext Available Row ")
- (princ row)
- (princ)
- )
- ;just a test--not necessary:
- (setq cell (cellstr row 1 1 1)) ; create cell string, such as
- ; "R1C1:R2C2", row col nrows ncols
- (poke chnl cell "-99") ;comment to flag end of sheet
- (princ)
- )
-
-
- ; Send a selection set to remote app, one by one.
- ; Demonstates use of entpokecell.
- (defun sendset2 ()
- (chkdde) ;Check open chnl, prompt user if not
- (setq sset (ssget)) ;get a selection set
- (setq idx 0)
- (setq en (ssname sset idx)) ;set en to first entity
- (setq row row1 col col1) ;starting spreadsheet cell
- (setq rowcnt 0)
- (while (not (null en))
- (setq rows (entpokecell chnl en row col)) ;fill cells with entity data
- ; list. rows is the number of items
- ; in list
- (setq row (+ row rows)) ;move down to bottom of that entity
- ; in spreadsheet
- (setq rowcnt (+ rowcnt rows))
- (setq idx (+ idx 1))
- (setq en (ssname sset idx)) ;set en to idx'th entity
- (princ "\nRow ")
- (princ row)
- (princ)
- )
- (setq sset nil)
- )
-
-
- ; Input data from remote app on all the entities in the drawing,
- ; and update any that have changed, with entmod. Entities
- ; are transferred in sections 100 rows each.
- ; Demonstrates DDE function "reqmod".
- (defun mod2 () ;Dynamic Data Exchange Sample
- ; Usage
- (chkdde) ;Check open chnl, prompt user if not
- (setq row row1 rows 0 modtot 0) ;start at top of spreadsheet
- (setq rowtot 0)
- (while (< rowtot rowcnt) ;while there are more rows to check
- ; based on how many were sent
- (setq item (cellstr row col1 100 4)) ;read in 100 rows at a time
- (princ item)
- (princ " ")
- (setq rows (reqmod chnl item)) ;get data from spreadsheet, and
- ; convert to entities
- (princ rows)
- (princ " ")
- (setq modcnt (modcount)) ;(modcount) gets the last
- ; count value
- (setq modtot (+ modtot modcnt)) ;update modified count.
- (setq row (+ row rows)) ;move down to bottom of that entity
- ; in spreadsheet
- (setq rowtot (+ rowtot rows))
- (princ "Row: ")
- (princ row)
- (princ "\n")
- )
- (princ "\nEntities modified: ")
- (princ modtot)
- (princ)
- )
-
-
- ; Make sure we have a DDE channel. Create one if not.
- (defun chkdde ()
- (setq chnl (getddechnl)) ;Ask ddelisp.exe if we have a DDE
- ; channel open
- (if (= 0 chnl) (progn
- (setq chnl (ddeprompt)) ;Try to load app, open channel. If
- ; fail, put up dialog for app,
- ; topic, and command line.
- (if (= 0 chnl) (progn
- (princ "No DDE conversation open\n")
- ; (quit)
- )
- (setglobals)
- )
- )
- )
- )
-
-
- ; Re-init AutoLISP globals for each new drawing.
- (defun setglobals ()
- (setq row1 3 col1 1 rowcnt 0 ddeflag T)
- (fprecision 4 0.01) ;Set transfer floating point
- ; precision and fuzz
- ; factor for compares
- (setvar "cmdecho" 0)
- ;(command "_handles" "_on")
- (sethandles) ;ADS/DDE function that checks and
- ; sets handles on if they're off.
- (setddeformat 1) ;Use handles, not ent names.
- (setq linkcommand "(moddrawing 3 20000) ")
- ;When hot link data comes in,
- ;request row 3 through 20000
- ;(or less if spreadsheet has less
- ;rows)
- (princ "DDE.LSP and DDELISP.EXE loaded\n")
- (princ)
- )
-
- ; Send a title to the spreadsheet
- (defun sendheading ()
- (setq cell (cellstr 1 2 1 1)) ;cell item row 1 col 2, 1 row, 1 col
- ;Test DDE functions; poke, request, and execute
- (poke chnl cell "AutoCAD Drawing Data")
- )
-
- ; To enable (quit) function, to emulate C "break" or "return"
- ;(defun *error*(msg) ;silent quit from function
- ; (prin1)
- ;)
-
- ; Initialize when loading dde.lsp.
- (if (null initiate) (progn ;DDELISP.EXE not loaded.
- (xload "ddelisp") ;ADS program that contains the DDE
- ; AutoLISP functions.
- )
- )
-
- (setq chnl (getddechnl)) ;Ask ddelisp.exe if we have a DDE
- ; channel open
- (setq app (getddeapp) topic (getddetopic))
- (setglobals)
-
-
- ;<end of file>
-